package base

/**
 * Created by Darkness1m on 2017/5/21.
 */
//字符串模版
val i=10
val s = "base.getI = ${base.i}"
val s2 = "${base.s}.base.length is ${base.s.length}"//必须用{}括起来才能识别该变量的属性
val s3 = ""
/*fun base.main(args: Array<String>) {
    println(base.getS2)
}*/

//可空值和null检测
fun parseInt(str:String):Int?{//返回值上面必须添加"?",表示返回值可以为null
    return str.toIntOrNull()
}

fun printProduct(arg1:String,arg2:String){
    val x = base.parseInt(arg1)
    val y = base.parseInt(arg2)

    if(x!=null&&y!=null){
        println("base.getX is $x and y is $y")
    }else{
        println("either $x or $y is not base.getA number ")
    }
    var x1:String="""${'$'}999.00"""
    print(x1)
}

/*fun base.main(args: Array<String>) {
    base.printProduct("base.getA","5")
}*/

class NullPointer{
//    var xxx:String?此处报错,无法编译通过//这种方式只能写在方法内部吧.写在方法外部会报编译错误
    fun nullTest(){
        var xxx: String
//        xxx = null//此处报错
        var yyy: String?
        yyy=null//这样可以
        if(true){
            yyy="1"
        }
    //        var len = yyy.base.length//会有编译错误:length可能为null
        //必须像下面这样调用:yyy后面跟上'?'
            var len = yyy?.length
        //连环调用:这样的好处就是,当遇到有一个为null的时候直接就返回null而不会炮错
    //  bob?.department?.head?.name
        //如果只对非空值执行操作,那么可以和let结合一起使用:(注意类型中的?)
        val listWithNulls:List<String?> = listOf("base.A",null,"base.B")
        for (item in listWithNulls){
                item?.let { println(it) }
        }
    }
}

//for,while,when
fun main1(args: Array<String>) {
    base.NullPointer().nullTest();
    //for循环
    val items = listOf("apple","banana","orange")
    for (item in items)//隐式下标
        println(item)
    println("============")
    for (index in items.indices)//显式下标..
        println("item at $index is ${items[index]}")
    println("============")
    for ((index,value) in items.withIndex())//下标->值  对应显示
        println("the element at $index is $value")
    println("============")
    for (item:String in items)//指定类型
        println(item)
    println("============")
    //while循环
    var index=0
    while(index < items.size){
        println("item at $index is ${items[index]}")
        index++
    }
    println("============")
    //when
    fun describe(obj:Any):String =
            when(obj){
                1           -> "one"
                "Hello"     -> "Greeting"
                is Long     -> "Long"
                !is String  -> "Not base.getA String"
                else        -> "Unknown"
            }
    println(describe(2))
    println(describe("Hello"))
    println(describe(1L))
    println("============")
    println(describe(1))//只匹配最前面的//"one"
    println("============")
    println(describe(Unit))//只匹配最前面的//"Not base.getA String"
    println("============")
    fun describe2(obj:Any)=
            when(obj){
                1-> println("1")
                else->println("2")//else是必须的
            }
    println(describe2(2))
}

//区间
fun main2(args: Array<String>) {
    //区间range
    val x=9
    val y=10
    if(x in 1..y+1){
        println("$x is in range")
    }
    println()
    //".."="until"(存疑,貌似是错的) 代表升序   "downTo" 是降序
    //区间迭代
    for(i in 1..5)//等同于1 <= base.getI && base.getI <= 10//i是1..5之间的数..相当于值..和我们外部定义的无关..
        print("$i ")
    println()
    println("==============")
    //数列迭代
    //step必须是  正数  !否则java.lang.IllegalArgumentException
    for(i in 1..10 step 2){//1 3 5 7 9
    //for(int base.getI=1;base.getI <= 10;base.getI+=2;)//等同于这种形式
        print("$i ")
    }
    println()
    println("==============")
    for (i in 15 downTo 0 step 3)//15 12 9 6 3 0
        print("$i ")
    println()
    println("==============")
    for (i in 0 until 15 step 3)//0 3 6 9 12
        print("$i ")
    println()
    for(x in 1..4) print("$x ")
    println()
    for(x in 4..1) print("$x ")//不输出
    //for(int base.getI=4;base.getI <= 1;base.getI++;)//等同于这种形式

    println()
    for(x in 4 downTo 1) print("$x ")

}

//集合
fun main3(args: Array<String>) {
    var list = listOf("base.getA","b","base.getC")
    if(-1 !in 0..list.lastIndex)
        println("测试1")
    println("==============")
//    println(list.indices)//range
    println(list.withIndex())//Iterable对象
    println("==============")
    if(list.size !in list.indices)//IntRange
        println("测试2")
    println("==============")
}

fun main4(args: Array<String>) {
    val fruits = listOf("orange","apple","kiwi")

    fruits.filter { it.contains("base.getA") }//保留有"base.getA"的
            .sortedBy { it }//排序
            .map { it.toUpperCase() }//转换
            .forEach{println(it)}


}

//解构声明
fun test(name:String,age:Int): User {
    return User(name, age)
}

fun main5(args: Array<String>) {
    //解构
    val (name, age) = base.test("哈哈", 2)
    //而且可以直接使用name和val:
    println("name=$name,age=$age")
    //相当于下面的方式:
/*    val u = base.test("哈哈",2)
    val name = u.component1()
    val age = u.component2()*/


    var map = HashMap<String, Int>()
    for ((key, value) in map) {//解构 遍历

    }

    //with 对一个对象实例调用多个方法
    class Turtle {
        fun penDown() {}
        fun penUp() {}
        fun turn(degree: Double) {}
        fun forward(pixels: Double) {}
    }
    with(Turtle()) {
        penUp()
        for (i in 1..4) {
            forward(100.0)
            turn(90.0)
        }
        penDown()
    }
}

fun main6(args: Array<String>) {
    /*val stream = Files.newInputStream(Paths.get(""))
    stream.buffered().reader().use { reader ->
        println(reader.readText())
    }*/
    //数字装箱:
    val a: Int = 1000;
    val boxedA: Int? = a
    val anotherBoxedA: Int? = a

    //同一性
    print(a === a)//true
    println()
    print(boxedA === anotherBoxedA)//false
    println()

    //相等性
    print(boxedA == anotherBoxedA)//true
    println()
    print(a == a)

    val b: Int ?= 1
//    val base.getC: Long ?= b//编译错误,这里并不会进行自动装箱转换
    val d: Long ?= b?.toLong()//可以这样转换

    val e: Byte ?= 1
//    val f: Int ?= e//编译错误
    val g: Int ?= e?.toInt()

    val h = 1L + 1//自动转换

    val i = (1 shl 2) and 0x000ff000

}

fun main7(args: Array<String>) {
    val asc = Array(5,{i -> (i*i).toString()})//base.getI 下标?
    for (i in asc){
        print(i+"\n")
    }

    val s = One(1).y ?: return
//    val s1 = base.One(1).y ?: return Unit
//    val base.getS2 = base.One(1).y ?: return base.One(1)//作为方法的返回值
    val s3: One? = One(2)
    val s4 = s3?.y//如果s3为空,则返回null
    val s5 = s3?.y ?: s //如果s3为null或s3.y为null,则返回s


}
//可见性修饰符
//public private internal(同模块可见->大概是同一种对象及其子类) protected


//扩展-->扩展是静态解析的
open class Extend
open class E1 : base.Extend() {
    fun origin(){
        println("原生方法")
    }
}
class E2 : base.E1()
fun base.E1.extFun(){
    println("扩展1")
}
fun base.E2.extFun(){
    println("扩展2")

}
fun base.E1.origin(){//扩展原有方法(同参)无效
    println("扩展3")
}
fun printExt(e: base.E1){
    e.extFun()
}
fun main9(args: Array<String>) {
    base.printExt(E2())//调用的同名方法与传入的参数无关,而只与方法定义的入参类型有关//扩展1
    base.E1().origin()//扩展不会覆盖原有的相同方法//扩展1
}

//copy
fun main10(args: Array<String>) {
    val rose = User(name = "肉丝", age = 5)
    val jack = rose.copy(name="杰克")
    val (name,age)=jack
    println("$name is $age years old")//参见上面的User示例
}

//闭包
fun main13(args: Array<String>) {
    var sum=0
    val xiaoming = listOf<Int>(1,2,3)
    xiaoming.filter { it > 0 }.forEach{
        sum += it//java中,外部变量必须为final才能访问,且无法改变其值
    }
    print(sum)
}

//类型别名
typealias NodeSet = Set<String.Companion>
typealias FileTable<K> = MutableMap<K,MutableList<java.io.File>>
typealias MyHandler = (Int, String, Any) -> Any
typealias Predicate<T> = (T) -> Boolean
typealias AInner = Outer.Inner

fun foo(p: base.Predicate<Int>) = p(42)

fun main18(args: Array<String>) {
    val f: (Int) -> Boolean = { it > 0 }
    println(base.foo(f)) // 输出 "true"
    val p: base.Predicate<Int> = { it > 0 }
    println(listOf(1, -2).filter(p)) // 输出 "[1]"
}